# -*- coding: utf-8 -*-
"""
-------------------------------------------------
Project Name: luffcity study project
File Name: client.py
Author: kij
Create Date: 2021/3/1
-------------------------------------------------
"""
# -*- coding: utf-8 -*-
"""
-------------------------------------------------
Project Name: luffcity study project
File Name: client.py
Author: kij
Create Date: 2021/2/28
-------------------------------------------------
"""
import json
import os
import socket
import shelve

from conn import setting
from conn.conn_client import NetDataUtils, MyFileUtils


class MyClient(object):
	"""
	用于链接和发送数据
	"""

	logon_dict = {
		'action_type': '',
	}

	def __init__(self, ip, port):
		self.conn = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
		self.conn.connect((ip, port))
		self.request = NetDataUtils(self.conn)
		# 用户名保存 登陆成功 链接后用于以后上传
		self.username = None
		# 存储当前 文件夹路径
		self.current_dir = None
		# 用于在输入框显示提示的内容，包括姓名，当前路径
		self.hint = None
		self.shelve_obj = shelve.open("luffy_db")

	def close_net(self):
		self.conn.close()
		self.logon_dict['action_type'] = 'exit'
		self.logon_dict['code'] = 400
		self.logon_dict['msg'] = '与系统断开'
		self.logon_dict['current_dir'] = '~'
		return self.logon_dict

	def auth(self, user_dict):
		"""用户认证"""
		# 发送数据
		self.username = user_dict['username']
		self.logon_dict['action_type'] = 'logon'
		self.logon_dict.update(user_dict)
		self.request.send_msg(json.dumps(self.logon_dict))
		# 接收服务器数据
		return self.request.get_msg()

	def update_file(self, file_path):
		# 生成上传文件需要的json数据
		myd_file_utils = MyFileUtils(file_path)
		myd_file_utils.file_md5()
		self.logon_dict['action_type'] = 'update_file'
		self.logon_dict['username'] = self.username
		self.logon_dict['current_dir'] = self.current_dir
		self.logon_dict.update(json.loads(str(myd_file_utils)))
		self.request.send_msg(json.dumps(self.logon_dict))
		self.request.send_file(myd_file_utils)
		return self.request.get_msg()

	def download_file(self, file_path):
		'''
		下载文件
		'''
		# 方便打包文件信息生成json
		myd_file_utils = MyFileUtils()
		myd_file_utils.file_path = file_path
		myd_file_utils.file_name = myd_file_utils.get_file_name(file_path)[-1]

		self.logon_dict['action_type'] = 'down_file'
		self.logon_dict['username'] = self.username
		self.logon_dict['current_dir'] = self.current_dir
		self.logon_dict.update(json.loads(str(myd_file_utils)))
		# 发送请求
		self.request.send_msg(json.dumps(self.logon_dict))
		# 拿到数据
		result_file_json = json.loads(self.request.get_msg().decode('utf-8'))
		# 下载数据{"file_name": "client.py", "file_path": "/Volumes/work/Code/Python Code/luffcity study project/module_three/day32/web/home/kijlee/client.py",
		# "file_size": 1824, "file_md5": "cb31c9e74d9e670f7de001505622ad48"}
		if result_file_json.get('code') == 200:
			file_dict = json.loads(result_file_json.get('data'))
			file_abs_path = file_dict.get('file_path')
			# 为断点续传作准备
			self.shelve_obj[file_abs_path] = [file_dict.get('file_size'), "%s.download" % file_dict.get('file_name')]
			print("-------未下载完的文件列表-------------", list(self.shelve_obj.keys()))
			# 不close不会保存
			self.shelve_obj.close()
			# 存储服务器文件路径 和大小
			local_path = os.path.join(setting.BASE_DIR, 'client', "%s.download" % file_dict.get('file_name'))
			file_utils = MyFileUtils()
			file_utils.file_path = local_path
			file_utils.file_size = file_dict.get('file_size')
			file_utils.file_name = file_dict.get('file_name')
			file_utils.md5 = file_dict.get('file_md5')

			# 保存文件的时候会生成校验的md5码
			file_md5 = self.request.save_file(file_utils)

			if file_utils.md5 == file_md5:
				print('下载完成')
				self.shelve_obj = shelve.open("luffy_db")
				del self.shelve_obj[file_abs_path]
				os.rename(local_path, os.path.join(setting.BASE_DIR, 'client', file_dict.get('file_name')))
		return result_file_json

	def ls_file(self):
		# 发送数据
		self.logon_dict['username'] = self.username
		self.logon_dict['action_type'] = 'ls'
		self.logon_dict['current_dir'] = self.current_dir
		# 如果在其他目录下 需要将在那个目录下传递过去
		self.request.send_msg(json.dumps(self.logon_dict))
		# 拿到服务器返回的数据
		return self.request.get_msg()

	def dir_file(self):
		# 发送数据
		self.logon_dict['username'] = self.username
		self.logon_dict['action_type'] = 'dir'
		self.logon_dict['current_dir'] = self.current_dir
		self.request.send_msg(json.dumps(self.logon_dict))
		# 拿到服务器返回的数据
		return self.request.get_msg()

	def cd_file(self, file_path):
		# 发送数据
		self.logon_dict['username'] = self.username
		self.logon_dict['action_type'] = 'cd'
		self.logon_dict['current_dir'] = self.current_dir
		# 添加cd路径
		self.logon_dict.update(file_path)
		self.request.send_msg(json.dumps(self.logon_dict))
		# 拿到服务器返回的数据 并返回给上一层
		return json.loads(self.request.get_msg())

	def mkdir_file(self, file_path):
		# 发送数据
		self.logon_dict['username'] = self.username
		self.logon_dict['action_type'] = 'mkdir'
		self.logon_dict.update(file_path)
		self.logon_dict['current_dir'] = self.current_dir
		self.request.send_msg(json.dumps(self.logon_dict))
		# 拿到服务器返回的数据 返回上一层
		return self.request.get_msg()

	def re_get_file(self,re_get_dict):
		# 发送数据
		self.logon_dict['username'] = self.username
		self.logon_dict['action_type'] = 're_get'
		self.logon_dict.update(re_get_dict)
		self.logon_dict['current_dir'] = self.current_dir
		self.request.send_msg(json.dumps(self.logon_dict))

		# 服务器发过来的数据  检查文件是否存在等
		result_file_json = json.loads(self.request.get_msg().decode('utf-8'))
		print(result_file_json)
		if result_file_json.get('code') == 200:
			# 接收文件

			file_dict = json.loads(result_file_json.get('data'))
			file_abs_path = file_dict.get('file_path')
			# 为断点续传作准备
			self.shelve_obj[file_abs_path] = [file_dict.get('file_size'), "%s.download" % file_dict.get('file_name')]
			print("-------未下载完的文件列表-------------", list(self.shelve_obj.keys()))
			# 不close不会保存
			self.shelve_obj.close()
			# 存储服务器文件路径 和大小
			local_path = os.path.join(setting.BASE_DIR, 'client', "%s.download" % file_dict.get('file_name'))
			file_utils = MyFileUtils()
			file_utils.file_path = local_path
			file_utils.file_size = file_dict.get('file_size')
			file_utils.file_name = file_dict.get('file_name')
			file_utils.md5 = file_dict.get('file_md5')

			# 保存文件的时候会生成校验的md5码
			self.request.re_save_file(file_utils,self.logon_dict.get('already_received_size'))


			if file_utils.md5 == json.loads(result_file_json.get('data')).get('file_md5'):
				print('下载完成')
				self.shelve_obj = shelve.open("luffy_db")
				del self.shelve_obj[file_abs_path]
				self.shelve_obj.close()
				os.rename(local_path, os.path.join(setting.BASE_DIR, 'client', file_dict.get('file_name')))
		return result_file_json

